import os
import sys
import stat
import win32con
import win32file

CHUNK_SIZE = 1 << 16

class shared_file(object):

    def __init__(self, fname, mode='r'):
        open_flags = 0
        file_flags = 0
        exist_flags = win32con.OPEN_EXISTING

        if 'r' in mode:
            open_flags |= win32con.GENERIC_READ
            file_flags |= win32con.FILE_FLAG_SEQUENTIAL_SCAN
        if 'w' in mode:
            open_flags |= win32con.GENERIC_WRITE
            exist_flags = win32con.CREATE_ALWAYS

        self.h = win32file.CreateFile(
            fname,
            open_flags,
            win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
            None,
            exist_flags,
            file_flags,
            None)

    def read(self, amt=None):
        if amt is None:
            amt = len(self)

        chunks = []
        bytes_read = 0
        while True:
            rc, chunk = win32file.ReadFile(self.h, CHUNK_SIZE)
            if rc == 0:
                if chunk:
                    chunks.append(chunk)
                    bytes_read += len(chunk)
                else:
                    # No more data to read.
                    break
            else:
                # Else What????
                break
            if bytes_read >= amt:
                break
        return ''.join(chunks)

    def __iter__(self):
        while 1:
            chunk = self.read(CHUNK_SIZE)
            if not chunk:
                raise StopIteration
            yield chunk

    def write(self, data):
        rc, written = win32file.WriteFile(self.h, data)
        return written

    def close(self):
        self.h.Close()

    def __len__(self):
        return win32file.GetFileSize(self.h)

    def __nonzero__(self):
        return True

if __name__ == '__main__':
    os.remove(sys.argv[1])
    os.remove(sys.argv[2])

    print os.path.exists(sys.argv[1])
    print os.path.exists(sys.argv[2])

    f1 = shared_file(sys.argv[1], 'w')
    f2 = shared_file(sys.argv[1], 'r')

    win32file.CreateHardLink(sys.argv[2], sys.argv[1])

    f3 = shared_file(sys.argv[2], 'w')
    f4 = shared_file(sys.argv[2], 'r')

    print 'f1'
    print 'current size', len(f1)
    print f1.write('X' * 100), 'bytes written'
    print 'current size', len(f1)

    print 'f2'
    print f2.read()

    print 'f3'
    print 'current size', len(f3)
    print f3.write('Y' * 100), 'bytes written'
    print 'current size', len(f3)

    print 'f4'
    for chunk in f4:
        print chunk

    f2.close()
    f2 = shared_file(sys.argv[1], 'r')
    
    print 'f2'
    print f2.read()

    f1.close()
    f2.close()
    f3.close()
    f4.close()
    
    os.remove(sys.argv[1])
    os.remove(sys.argv[2])
